#include "Shop.h"

// 构造商店
Shop::Shop(Player &p):p(p)
{
    // 设置商店图标
    this->SetSymbol("🛒");
    // 武器
    PropVec.push_back(std::make_shared<Weapon>("屠龙剑⚔️ ", 10, 10, 0));
    PropVec.push_back(std::make_shared<Weapon>("破甲弓🏹", 20, 20, 0));
    PropVec.push_back(std::make_shared<Weapon>("激光枪🔫", 30, 30, 0));
    // 防具
    PropVec.push_back(std::make_shared<Armor>("反伤刺甲🦺", 10, 10, 0));
    PropVec.push_back(std::make_shared<Armor>("魔女斗篷👘", 20, 20, 0));
    PropVec.push_back(std::make_shared<Armor>("不死护甲🥼", 30, 30, 0));
    // 药水
    PropVec.push_back(std::make_shared<Medicine>("余霞成绮🍷", 10, 10, 0));
    PropVec.push_back(std::make_shared<Medicine>("落日黄昏🍹", 20, 20, 0));
    PropVec.push_back(std::make_shared<Medicine>("玛格丽特🍸", 50, 50, 0));
}

// 展示商店
void Shop::show()
{
    while(1)
    {
        system("clear");
        p.show();
        std::cout << std::endl;
        std::cout << "==================🎃 欢迎来到商店 🎃==================\n";
        int i = 0;
        // 循环展示商品
        for(; i < PropVec.size(); i++)
        {
            if(i == 3 || i == 6)
                std::cout << std::endl;
            std::cout << i + 1 << "、";
            PropVec[i]->show();
        }
        std::cout << i + 1 << "、当物品" << std::endl;
        std::cout << i + 2 << "、退出" << std::endl;
        std::cout << "请输入你要购买的商品编号:";
        int choice = 0;
        std::cin >> choice;
        if(choice == i + 1)
        {
            SellProp(p);
            continue;
        }
            
        if(choice == i + 2)
        {
            std::cout << "欢迎再次光临!🥳\n";
            sleep(1);
            return;
        }

        // 检查输入流是否错误
        while (std::cin.fail() || choice < 1 || choice > i + 1)
        {
            if (std::cin.fail())
            {
                std::cin.clear(); // 清除错误标志
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 丢弃无效输入
            }
            std::cout << "没有该选项哦，请重新选择!" << std::endl;
            std::cin >> choice;
        }

        if(p.GetGold() < PropVec[choice - 1]->GetPrice())
        {
            std::cout << "你的金币不足，快去刷怪赚取金币吧少年！🫵" << std::endl;
            sleep(1);
        }
        else
        {
            // 刷新玩家的金币（|玩家金币 - 商品价格|）
            p.SetGold(std::max(p.GetGold() - PropVec[choice - 1]->GetPrice(), 0));
            std::cout << "恭喜你成功购买了|" << PropVec[choice - 1]->GetName() << "|" << std::endl;
            // 把商品放入玩家背包
            p.InsertBag(PropVec[choice - 1]);
            sleep(1);
        }  
    }
}

// 当物品
void Shop::SellProp(Player &p)
{
    while (1)
    {
        system("clear");
        int i = 0;
        for (; i < p.GetBag().size(); i++)
        {
            std::cout << i + 1 << "、";
            p.GetBag()[i]->show();
        }
        std::cout << i + 1 << "、" << "退出" << std::endl;
        std::cout << "请选择你要当掉的物品:";
        int choice = 0;
        std::cin >> choice;
        // 检查输入流是否错误
        while (std::cin.fail() || choice < 1 || choice > i + 1)
        {
            if (std::cin.fail())
            {
                std::cin.clear(); // 清除错误标志
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 丢弃无效输入
            }
            std::cout << "没有该选项哦，请重新选择!" << std::endl;
            std::cin >> choice;
        }
        if (choice == i + 1)
            return;

        // 如果是武器
        // dynamic_cast尝试将玩家背包中选择的物品转换为Weapon*类型，如果转换成功，说明该物品是武器类型
        // ptr是一个指向Weapon对象的指针，如果转换成功，它会指向背包中选择的武器；如果转换失败，则为nullptr
        if (auto ptr = dynamic_cast<Weapon *>(p.GetBag()[choice - 1].get()); ptr != nullptr)
        {
            std::cout << "是否确定要当掉该武器？(y/n)";
            sleep(1);
            char c = 0;
            std::cin >> c;
            if (c == 'y' || c == 'Y')
            {
                if (p.GetW() == ptr)
                {
                    std::cout << "装备正穿戴在身上，请卸下后再来当吧！" << std::endl;
                    sleep(1);
                    continue;
                }
                std::cout << "已成功当出，半价入账！" << std::endl;
                sleep(1);
                // 更新金币
                p.SetGold(p.GetGold() + (p.GetBag()[choice - 1]->GetPrice() / 2));
                // 删除背包中的物品
                p.GetBag().erase(p.GetBag().begin() + (choice - 1));
            }
            continue;
        }

        // 如果是防具
        if (auto ptr = dynamic_cast<Armor *>(p.GetBag()[choice - 1].get()); ptr != nullptr)
        {
            std::cout << "是否确定要当掉该防具？(y/n)";
            sleep(1);
            char c = 0;
            std::cin >> c;
            if (c == 'y' || c == 'Y')
            {
                if (p.GetA() == ptr)
                {
                    std::cout << "装备正穿戴在身上，请卸下后再来当吧！" << std::endl;
                    sleep(1);
                    continue;
                }
                std::cout << "已成功当出，半价入账！" << std::endl;
                sleep(1);
                // 更新金币
                p.SetGold(p.GetGold() + (p.GetBag()[choice - 1]->GetPrice() / 2));
                // 删除背包中的物品
                p.GetBag().erase(p.GetBag().begin() + (choice - 1));
            }
            continue;
        }

        // 如果是药水
        if (auto ptr = dynamic_cast<Medicine *>(p.GetBag()[choice - 1].get()); ptr != nullptr)
        {
            std::cout << "是否确定要当掉该药水？(y/n)";
            sleep(1);
            char c = 0;
            std::cin >> c;
            if (c == 'y' || c == 'Y')
            {
                std::cout << "已成功当出，半价入账！" << std::endl;
                sleep(1);
                // 更新金币
                p.SetGold(p.GetGold() + (p.GetBag()[choice - 1]->GetPrice() / 2));
                // 删除背包中的物品
                p.GetBag().erase(p.GetBag().begin() + (choice - 1));
            }
            continue;
        }
    }
}
